//Air001_INA219_mini.ino 验证OK
#include <Wire.h>

// INA219寄存器地址
#define INA219_ADDR 0x40
#define INA219_REG_CONFIG     0x00
#define INA219_REG_SHUNTVOLT  0x01  // 分流电压
#define INA219_REG_BUSVOLT    0x02  // 总线电压
#define INA219_REG_POWER      0x03  // 功率寄存器
#define INA219_REG_CURRENT    0x04  // 电流寄存器
#define INA219_REG_CALIB      0x05  // 校准寄存器

// 配置参数 (32V范围, 2A量程, 0.1Ω分流电阻)
#define CAL_VALUE     4096    // 1A是2048,2A是4096

// 写入寄存器
void writeReg(uint8_t reg, uint16_t value) {
  Wire.beginTransmission(INA219_ADDR);
  Wire.write(reg);
  Wire.write((uint8_t)(value >> 8));    // 高字节
  Wire.write((uint8_t)(value & 0xFF));  // 低字节
  Wire.endTransmission();
  delay(1);
}

// 读取寄存器
uint16_t readReg(uint8_t reg) {
  Wire.beginTransmission(INA219_ADDR);
  Wire.write(reg);
  Wire.endTransmission(false); // 保持连接
  Wire.requestFrom(INA219_ADDR, (uint8_t)2);
  //return (Wire.read() << 8) | Wire.read();
  uint16_t value = Wire.read() << 8;
  value |= Wire.read();
  return value;
}

// 读取分流电压 (mV)
float getShuntVoltage_mV() {
  int16_t value = (int16_t)readReg(INA219_REG_SHUNTVOLT);
  return value * 0.01;  // LSB=10μV=0.01mV
}

// 读取总线电压 (V)
float getBusVoltage_V() {
  uint16_t value = readReg(INA219_REG_BUSVOLT);
  return (value >> 3) * 0.004;  // 每个LSB=4mV=0.004V
}

// 读取电流 (A)
float getCurrent_A() {
  writeReg(INA219_REG_CALIB, CAL_VALUE);  // 确保校准值已写入
  int16_t value = readReg(INA219_REG_CURRENT);
  return value * 0.0001;  // LSB=100μA=0.0001A
}

// 读取功率 (mW)
float getPower_mW() {
  writeReg(INA219_REG_CALIB, CAL_VALUE);  // 确保校准值已写入
  uint16_t value = readReg(INA219_REG_POWER);
  return value * 2;   // LSB=2mW
}

void setup() {
//  Serial.begin(115200);
  Wire.begin();
  //Wire.setClock(100000); // 设置I2C时钟为100kHz
  delay(10);

  // 先配置INA219
  // uint16_t config = INA219_CONFIG_BVOLTAGERANGE_32V |
  //                   INA219_CONFIG_GAIN_8_320MV | INA219_CONFIG_BADCRES_12BIT |
  //                   INA219_CONFIG_SADCRES_12BIT_1S_532US |
  //                   INA219_CONFIG_MODE_SANDBVOLT_CONTINUOUS;
  // uint16_t config = 0x2000 | 0x1800 | 0x0180 | 0x0018 | 0x07;
  writeReg(INA219_REG_CONFIG, 0x399F);  //最终结果是0x399F
  delay(10);
  // 再设置校准值
  writeReg(INA219_REG_CALIB, CAL_VALUE);  // 32V, 2A范围
  delay(10);
  // 可选:验证配置
//  uint16_t configCheck = readReg(INA219_REG_CONFIG);
//  if(configCheck != 0x399F) {
//    Serial.print("配置错误! 读取值: 0x");
//    Serial.println(configCheck, HEX);
//  }
//
//  Serial.println("INA219 初始化完成");
}

void loop() {
  float shuntVoltage_mV = getShuntVoltage_mV();
  float busVoltage_V = getBusVoltage_V();
  float voltage_V = busVoltage_V + (shuntVoltage_mV / 1000.0); // 组合电压
  float current_A = getCurrent_A();
  float power_mW = getPower_mW();
  
//  Serial.print("Bus V: "); Serial.print(busVoltage_V, 3); Serial.println(" V");
//  Serial.print("Shunt V: "); Serial.print(shuntVoltage_mV, 3); Serial.println(" mV");
//  Serial.print("Voltage: "); Serial.print(voltage_V, 3); Serial.println(" V");
//  Serial.print("Current: "); Serial.print(current_A, 4); Serial.println(" A");
//  Serial.print("Power:   "); Serial.print(power_mW, 1); Serial.println(" mW");
//  Serial.println();
  
  delay(1000);
}
